import { input } from 'cc';
import { EventTouch } from 'cc';
import { PhysicsSystem } from 'cc';
import { Input } from 'cc';
import { Camera } from 'cc';
import { _decorator, Component, Node } from 'cc';
import { Brick } from './Brick';
import { EVENT_NAMES } from '../../../utils/Enums';
import { UIManager } from '../../../framework/ui/uimanager/UIManager';
import { Vec2 } from 'cc';
import { BricksCtrl } from './BricksCtrl';
import { Vec3 } from 'cc';
import DataMgr from '../../../utils/DataMgr';
import Design from '../../../utils/Design';
import Config from '../../../utils/Config';
import { GGResource } from '../../../framework/core/base/GGResource';
import { JsonAsset } from 'cc';
import { geometry } from 'cc';
import { Layers } from 'cc';
import { director } from 'cc';
import { AudioManager } from '../../../common/src/manager/AudioManager';
const { ccclass, property } = _decorator;

@ccclass('GameCtrl')
export class GameCtrl extends Component {
    @property({ type: Camera, displayName: "摄像头" })
    camera: Camera;
    
    @property({ type: Node, displayName: "地板" })
    rotateNode: Node;

    // 块控制器
    private bricksCtrl: BricksCtrl = null
    
    private startTouchPos: Vec2 = new Vec2(); // 触摸开始位置
    private isTouching: boolean = false; // 是否正在触摸
    private rotationSpeed: number = 0.25; // 旋转速度，值越大旋转越快

    private selecColumn: Node = null    // 当前选中的地板
    private moveColumn: Node = null     // 当前移动选中的列
    private lastColumn: Node = null     // 上一个移动的列

    private inGame: boolean = false     // 是否游戏开始了
    private countdownTime: number = -1  // 倒计时
    
    async start() {
        this.initValues()
        this.initListener()
        await this.initPanels()
        // this.loadGameLevel()

        gg.systemEvent.emit(EVENT_NAMES.ON_GAME_START)
    }

    protected onDestroy(): void {
        input.off(Input.EventType.TOUCH_START)
        input.off(Input.EventType.TOUCH_MOVE)
        input.off(Input.EventType.TOUCH_END)

        gg.systemEvent.off(EVENT_NAMES.DRAG_OPERATE, this.onDragOperateBrick, this)
        gg.systemEvent.off(EVENT_NAMES.ON_GAME_END, this.gameEnd, this)

        gg.systemEvent.off(EVENT_NAMES.ON_GAME_START, this.loadGameLevel, this)
    }

    protected update(dt: number): void {
        if (this.inGame) {
            this.countdownTime -= dt
            if (this.countdownTime <= 0) {
                this.inGame = false
                gg.systemEvent.emit(EVENT_NAMES.ON_GAME_END, false)
            } else {
                const info = {time: this.countdownTime}
                gg.systemEvent.emit(EVENT_NAMES.UPDATE_GAME_INFO, info)
            }
        }
    }

    // ------------------- 初始化 ------------------- //
    private initValues() {
        this.bricksCtrl = this.getComponent(BricksCtrl)
    }

    private initListener() {
        input.on (Input.EventType.TOUCH_START, this.onTouchStart, this)
        input.on (Input.EventType.TOUCH_MOVE, this.onTouchMove, this)
        input.on (Input.EventType.TOUCH_END, this.onTouchEnd, this)

        gg.systemEvent.on(EVENT_NAMES.DRAG_OPERATE, this.onDragOperateBrick, this)
        gg.systemEvent.on(EVENT_NAMES.ON_GAME_END, this.gameEnd, this)

        gg.systemEvent.on(EVENT_NAMES.ON_GAME_START, this.loadGameLevel, this)
    }

    private async initPanels() {
        await UIManager.open("operate:res/prefab/OperatePanel")
        await UIManager.open("property:res/prefab/PropertyPanel")
        await UIManager.open("info:res/prefab/InfoPanel")
        await UIManager.open("menu:res/prefab/MenuPanel")
    }

    // ------------------- 内部方法 ------------------- //
    // 加载关卡
    private loadGameLevel() {
        Config.dragColorArray = [-1, -1, -1, -1]

        const self = this
        GGResource.load("tables:json/关卡/关卡" + DataMgr.currentLevel, JsonAsset).then((ja: JsonAsset) => {
            DataMgr.colorPool = ja.json["colors"]
            DataMgr.countDown = ja.json["max"]
            // DataMgr.countDown = 10
            self.countdownTime = DataMgr.countDown

            self.inGame = true
            self.bricksCtrl.onNewGame(ja)
            
            gg.systemEvent.emit(EVENT_NAMES.PROPERTY_REFRESH)
        });
    }

    // 射线检查，来获取块
    private rayCheck(pos: Vec2) {
        let ray = this.camera.screenPointToRay(pos.x, pos.y)        
        // 如果选中了节点
        if (PhysicsSystem.instance.raycastClosest(ray) == true) {
            // 获取射线最短的检测结果
            var checkNode = PhysicsSystem.instance.raycastClosestResult.collider.node
            return checkNode
        }

        return null
    }

    // 获取当前位置的六边形块
    private getCurrentBrick(loc: Vec2): Brick {
        const result = this.rayCheck(loc)
        if (result != null) {
            var brickCom = result.getComponent(Brick)
            if (brickCom) {
                return brickCom
            }
        }

        return null
    }
    
    // 获取到从屏幕转到世界坐标的位置
    private getWorldPositionFromScreen(touchLocation: Vec3): Vec3 {
        // 获取触摸点在屏幕上的位置并转换为世界坐标系下的3D坐标
        const ray = this.camera.screenPointToRay(touchLocation.x, touchLocation.y);
        const distance = (Design.dragFloorHeight - this.camera.node.worldPosition.y) / ray.d.y

        const worldPos = new Vec3();
        ray.computeHit(worldPos, distance);

        // 保持 Y 轴位置不变
        worldPos.y = Design.dragFloorHeight;
        return worldPos;
    }

    // 将屏幕坐标转换为射线
    private screenPointToRay(screenPos: Vec2) {
        if (this.camera) {
            const ray = new geometry.Ray();
            this.camera.screenPointToRay(screenPos.x, screenPos.y, ray);
            return ray;
        }
        return null;
    }

    // ------------------- 事件 ------------------- //
    private onTouchStart(event: EventTouch) {
        if (DataMgr.isUsingExchange) {
            const brickCom = this.getCurrentBrick(event.getLocation())
            if (brickCom != null) {
                this.selecColumn = this.bricksCtrl.getBricksAt(brickCom.x, brickCom.z)
                if (this.selecColumn != null) {
                    this.selecColumn.position = new Vec3(this.selecColumn.position.x, this.selecColumn.position.y + 1, this.selecColumn.position.z)
                }
            }
            
            this.isTouching = true;
        } else {
            // 记录触摸开始位置
            event.getStartLocation(this.startTouchPos);
            this.isTouching = true;
        }
    }

    private onTouchMove(event: EventTouch) {
        if (!this.isTouching) return;

        if (DataMgr.isUsingExchange) {
            const brickCom = this.getCurrentBrick(event.getLocation())
            if (brickCom != null) {
                const moveFloor = this.bricksCtrl.getBricksAt(brickCom.x, brickCom.z)
                if (moveFloor != this.selecColumn) {
                    if (moveFloor != this.moveColumn) {
                        this.moveColumn = moveFloor
                        
                        if (this.selecColumn != null && this.moveColumn != null) {
                            if (this.lastColumn) {
                                this.bricksCtrl.resetColumnAt(this.lastColumn)
                            }

                            this.bricksCtrl.exchangeColumn(this.selecColumn, this.moveColumn)

                            if (this.lastColumn != this.moveColumn) {
                                this.lastColumn = this.moveColumn
                            }
                        }
                    }
                }
            }
    
        } else {
            // 获取当前触摸位置
            const touchPos = event.getLocation(new Vec2());
            const deltaX = touchPos.x - this.startTouchPos.x; // 计算滑动的水平距离
    
            // 根据滑动距离计算旋转角度
            const rotationY = deltaX * this.rotationSpeed;
    
            // 更新目标节点的旋转
            const currentRotation = this.rotateNode.eulerAngles;
            this.rotateNode.setRotationFromEuler(new Vec3(currentRotation.x, currentRotation.y + rotationY, currentRotation.z));
    
            // 更新开始位置
            this.startTouchPos.set(touchPos);
        }
    }

    // 触摸屏幕，目标为选中的 3D 对象
    private onTouchEnd(e: EventTouch): void {
        if (DataMgr.isUsingExchange) {
            if (this.selecColumn) {
                if (this.moveColumn) {
                    this.bricksCtrl.exchangeColumn(this.selecColumn, this.moveColumn, true)
                    AudioManager.playSound("audio:common/交换音效")
                } else {
                    this.bricksCtrl.resetColumnAt(this.selecColumn)
                }
                
                this.moveColumn = null
                this.selecColumn = null
            }

            DataMgr.isUsingExchange = false
            gg.systemEvent.emit(EVENT_NAMES.SET_CLICKED_EXCHANGE_REMIND, false)
        } else {
            const brickCom = this.getCurrentBrick(e.getLocation())
            if (brickCom) {
                this.bricksCtrl.onBrickClicked(brickCom)
            }
        }
    }

    // 拖拽操作块
    private onDragOperateBrick(node: Node, pos: Vec2, colors: number[]) {
        const result = this.rayCheck(pos)
        if (result != null) {
            var brickCom = result.getComponent(Brick)
            if (brickCom) {
                gg.systemEvent.emit(EVENT_NAMES.DRAG_OPERATE_RESULT, node, true)
                this.bricksCtrl.pushBrickToTower(brickCom.x, brickCom.z, colors)
                // this.bricksCtrl.pushAnimAt(brickCom.x, brickCom.z)
                return
            }
        }

        gg.systemEvent.emit(EVENT_NAMES.DRAG_OPERATE_RESULT, node, false)
    }

    // 游戏结束
    private gameEnd(result: boolean) {
        if (result) {
            UIManager.open("win:res/prefab/WinPanel")
        } else {
            UIManager.open("lose:res/prefab/LosePanel")
        }

        // UIManager.open("win:res/prefab/WinPanel")
    }
}


